/**
 * Author: ling
 * Create Time: 2018-12-03 14:56
 * Description: 迭代器模式
 */
// 实现自己的each函数
each = function (array, callback) {
  for (let i = 0, len = array.length; i < len; i++) {
    callback.call(array[i], i, array[i])
  }
};
each([1, 2, 3, 4], function (index, value) {
  console.log(index, value)
});

// 内部迭代器，外部迭代器

// 内部迭代器：内部规则已经提前定义好了，无法同时迭代两个数组

// 判断两个数组是否完全相等
compareArray = function (arr1, arr2) {
  if(arr1.length !== arr2.length) {
    return false
  }

  each(arr1, function (index, value) {
    if(arr2[index] !== value) {
      return false
    }
  });

  return true
};

// 外部迭代器：必须显式申明迭代的下一个元素
Iterator = function (obj) {
  let current = 1;

  let next = function () {
    ++current;
  };

  let isDone = function () {
    return obj.length <= current
  };

  let getCurrItem = function () {
    return obj[current]
  };

  return {
    next,
    isDone,
    getCurrItem
  }
};

compareArray = function(iterator1, iterator2) {
  while (!iterator1.isDone() || !iterator2.isDone()) {
    if(iterator1.getCurrItem() !== iterator2.getCurrItem()) {
      return false
    }

    iterator1.next();
    iterator2.next();
  }

  return true
};

console.log(compareArray(Iterator([1, 2, 3]), Iterator([1, 2, 3, 4])));

// 迭代器模式在浏览上传文件选择方式的应用
getActiveUpload = function () {
  try {
    // IE上传控件
    return new ActiveXObject("TXFTNActiveX.FTNUpload");
  } catch (e) {
    return false
  }
};

getFlashUploadObj = function() {
  if (supportFlash()) {
    let node = document.createElement('object');
    node.type = 'application/x-shockwave-flash';
    return document.body.appendChild(node);
  }

  // supportFlash函数未提供
  return false;
};

getFormUploadObj = function () {
  let input = document.createElement('input');
  input.type = 'file';
  input.name = 'file';

  return document.body.appendChild(input)
};

iteratorUploadObj = function () {
  for (let fn of arguments) {
    let uploadObj = fn();
    if(uploadObj !== false) {
      return uploadObj
    }
  }
};
iteratorUploadObj(getActiveUpload, getFlashUploadObj, getFormUploadObj);
